home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 January / enter-2004-01.iso / files / maxima-5.9.0.exe / {app} / share / maxima / 5.9.0 / emacs / emaxima.el < prev    next >
Encoding:
Text File  |  2003-02-09  |  71.3 KB  |  1,997 lines

  1. ;; emaxima.el  Mode for interaction with Maxima from TeX buffer
  2. ;; Written 2/12/1991 by Dan Dill dan@chem.bu.edu
  3. ;; Modified for Maxima by Jay Belanger
  4.  
  5. ;; Copyright (C) 1991, 1993 Dan Dill (dan@chem.bu.edu) 
  6. ;;               1999-2001 Jay Belanger (belanger@truman.edu)
  7.  
  8. ;; Author: Dan Dill
  9. ;;         Jay Belanger
  10. ;; Maintainer: Jay Belanger <belanger@truman.edu>
  11. ;; $Name:  $
  12. ;; $Revision: 1.7 $
  13. ;; $Date: 2002/09/06 16:55:10 $
  14. ;; Keywords: maxima, emaxima
  15.  
  16. ;; This program is free software; you can redistribute it and/or
  17. ;; modify it under the terms of the GNU General Public License as
  18. ;; published by the Free Software Foundation; either version 2 of
  19. ;; the License, or (at your option) any later version.
  20. ;;          
  21. ;; This program is distributed in the hope that it will be
  22. ;; useful, but WITHOUT ANY WARRANTY; without even the implied
  23. ;; warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  24. ;; PURPOSE.  See the GNU General Public License for more details.
  25. ;;          
  26. ;; You should have received a copy of the GNU General Public
  27. ;; License along with this program; if not, write to the Free
  28. ;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  29. ;; MA 02111-1307 USA
  30. ;;
  31. ;;
  32. ;; Please send suggestions and bug reports to <belanger@truman.edu>. 
  33. ;; The latest version of this package should be available at
  34. ;; ftp://vh213601.truman.edu/pub/Maxima
  35. ;; You will need, in addition to this file,
  36. ;; maxima.el, maxima-font-lock.el, maxima-symbols.el, and emaxima.sty
  37.  
  38. ;;; Commentary:
  39.  
  40. ;;  See the file EMintro.ps for a quick introduction.
  41.  
  42. (require 'maxima)
  43. (provide 'emaxima)
  44.  
  45. ;;;; The variables that the user may wish to change
  46.  
  47. (defgroup emaxima nil
  48.   "Maxima mode"
  49.   :prefix "emaxima-"
  50.   :tag    "EMaxima")
  51.  
  52. (defcustom emaxima-use-tex 'auctex
  53.   "Possible modes to use within EMaxima.
  54. Possible choices are 'auctex, 'tex or nil"
  55.   :group 'emaxima
  56.   :type '(choice :menu-tag "TeX style"
  57.                  :tag      "TeX style"
  58.                  (const auctex)
  59.                  (const tex) 
  60.                  (const nil)))
  61.  
  62. (defcustom emaxima-tex-lisp-file (locate-library "emaxima.lisp" t)
  63.   "The file to be loaded that allows TeX output."
  64.   :group 'emaxima
  65.   :type '(file))
  66.  
  67. (defcustom emaxima-abbreviations-allowed t
  68.   "If non-nil, then `...' abbreviations are allowed in cell labels 
  69. and references. Note that enabling this options will slow cell and 
  70. package assembly."
  71.   :group 'emaxima
  72.   :type '(boolean))
  73.  
  74. (defcustom emaxima-max-references 5
  75.   "Number of references in a cell below which cell references are fetched
  76. as needed, scanning the entire document for each reference.  At or above this
  77. number, all cells in a document for the given filename are precollated in a
  78. single scan of the document."
  79.   :group 'emaxima
  80.   :type '(integer))
  81.  
  82. (defcustom emaxima-temp-dir "/tmp/"
  83.   "Directory for temporary files.
  84. Specify \"\" to use the directory of the EMaxima document buffer."
  85.   :group 'emaxima
  86.   :type '(directory))
  87.  
  88. ;;; Other variables and constants
  89.  
  90. (defvar emaxima-zap-file nil
  91.   "Temporary file name used for text being sent as input to Maxima.")
  92.  
  93. (defvar emaxima-dereference-path nil
  94.   "List of buffers referenced in cell assembly.
  95. Used by `emaxima-dereference-buffer' to detect self-reference.")
  96.  
  97. (defvar emaxima-zap-file-prefix nil
  98.   "Global variable used as prefix to make unique buffer names for cell 
  99. and package assembly.")
  100.  
  101. (defvar emaxima-error-point nil
  102.   "Buffer position where error detected.")
  103.  
  104. (defvar emaxima-buffer-alist nil
  105.   "Alist of temporary buffers associate with cells `file:part'.
  106. The buffers are used in package and cell assembly.")
  107.  
  108. (defvar emaxima-source-buffer nil
  109.   "Buffer from which emaxima-collate-cells works.")
  110.  
  111. ;;; Sending information to Maxima, and getting it back
  112.  
  113. (defun emaxima-last-maxima-output ()
  114.   "Copy the last output from Maxima."
  115.   (interactive)
  116. ;  (emaxima-wait)
  117.   (let ((out-start)
  118.     (out-end)
  119.         (nonewline nil)
  120.         (pr)
  121.         (i 0)
  122.     (old-buffer (current-buffer))
  123.         (maxima-buffer (get-buffer "*maxima*"))
  124.         (output))
  125.     (if (null maxima-buffer)
  126.         (message "No Maxima output buffer")
  127.       (save-excursion
  128.         (set-buffer maxima-buffer)
  129.     (goto-char (point-max))
  130.         (unless (maxima-finished-p)
  131.           (re-search-backward inferior-maxima-prompt))
  132.     (setq out-end (point))
  133.         (goto-char maxima-real-input-end)
  134.         (forward-line 1)
  135. ;    (re-search-backward inferior-maxima-prompt)
  136. ;        (goto-char (match-end 0))
  137. ;        (if (looking-at " *$")
  138. ;        (forward-line 1)
  139.         ;; Now, gcl inserts an extra blank line
  140. ;        (if (looking-at "^ *$")
  141. ;            (forward-line 1))
  142. ;          (forward-line 0)
  143. ;          (setq nonewline t))
  144.     (setq out-start (point))
  145.     (setq output 
  146.               (buffer-substring-no-properties out-start out-end))
  147.         (goto-char (point-max))))
  148. ;    (set-buffer old-buffer)
  149. ;    (when nonewline
  150. ;      (setq pr (1+ (string-match ")" output)))
  151. ;      (setq output (concat (make-string pr ? ) (substring output pr))))
  152.     output))
  153.  
  154. (defun emaxima-last-maxima-output-noprompt ()
  155.   "Return the last Maxima output, without the prompts"
  156.   (interactive)
  157.   (if (maxima-finished-p)
  158.       (emaxima-last-maxima-output)
  159.     (let* ((output (emaxima-last-maxima-output))
  160.            (newstring)
  161.            (i 0)
  162.            (beg)
  163.            (end)
  164.            (k))
  165.     ;; Replace the output prompt with spaces
  166.       (setq beg (string-match "\\(^([D][0-9]*) \\)" output))
  167.       (if (not beg)
  168.           output
  169.         (setq end (1+ (string-match ")" output beg)))
  170.         (setq newstring (substring output 0 beg))
  171.         (setq k (- end beg))
  172.         (while (< i k)
  173.           (setq newstring (concat newstring " "))
  174.           (setq i (1+ i)))
  175.         (concat newstring 
  176.                 (substring output 
  177.                            end))))))
  178.  
  179. (defun emaxima-last-maxima-output-tex-noprompt ()
  180.   "Return the last Maxima output, between the dollar signs."
  181.   (interactive)
  182.   (let* ((output (emaxima-last-maxima-output))
  183.          (begtex (string-match "\\$\\$" output))
  184.          (endtex (string-match "\\$\\$" output (1+ begtex))))
  185.     (concat
  186.      (substring output begtex (+ endtex 2))
  187.      "\n")))
  188.  
  189.  
  190. ;;; Some utility functions
  191.  
  192. (defun emaxima-insert-quote (arg)
  193.   "Insert a quote as appropriate"
  194.   (interactive "*P")
  195.   (cond
  196.    ((emaxima-cell-p)
  197.       (self-insert-command (prefix-numeric-value arg)))
  198.    ((eq emaxima-use-tex 'auctex)
  199.     (TeX-insert-quote arg))
  200.    ((eq emaxima-use-tex 'tex)
  201.     (tex-insert-quote arg))
  202.    (t (self-insert-command (prefix-numeric-value arg)))))
  203.  
  204. (defun emaxima-insert-dollar (arg)
  205.   "Insert a dollar sign as appropriate"
  206.   (interactive "*P")
  207.   (cond
  208.    ((emaxima-cell-p)
  209.     (self-insert-command (prefix-numeric-value arg)))
  210.    ((eq emaxima-use-tex 'auctex)
  211.     (TeX-insert-dollar arg))
  212.    ((eq emaxima-use-tex 'tex)
  213.     (skeleton-pair-insert-maybe arg))
  214.    (t (self-insert-command (prefix-numeric-value arg)))))
  215.  
  216. (defun emaxima-mark-file-as-emaxima ()
  217.   "Mark the file as an EMaxima buffer.
  218. The next time the file is loaded, it will then be in EMaxima mode"
  219.   (interactive)
  220.   (save-excursion
  221.     (goto-line 1)
  222.     (beginning-of-line)
  223.     (if (looking-at ".*-\\*-EMaxima-\\*-")
  224.     ()
  225.     (open-line 1)
  226.       (insert "%-*-EMaxima-*-"))))
  227.  
  228. (defun emaxima-load-tex-library ()
  229.   (when emaxima-tex-lisp-file
  230.     (maxima-single-string
  231.                            (concat "block(load(\"" 
  232.                                    emaxima-tex-lisp-file
  233.                                    "\"), linenum:linenum-1)$"))))
  234.  
  235. (defun emaxima-tex-on ()
  236.   (maxima-start)
  237.   (when emaxima-tex-lisp-file
  238.     (maxima-single-string "block(display2d:emaxima, linenum:linenum-1)$")))
  239.  
  240. (defun emaxima-tex-off ()
  241.   (maxima-start)
  242.   (when emaxima-tex-lisp-file
  243.     (maxima-single-string "block(display2d:true, linenum:linenum-1)$")))
  244.  
  245. ;;; Which type of cell, if any, is the point in.
  246.  
  247. (defun emaxima-cell-p ()
  248.   "Non-nil if point is in a Emaxima cell."
  249.   (let ((begin-re "^\\\\beginmaxima")
  250.         (end-re "^\\\\endmaxima")
  251.         (found nil))
  252.     (save-excursion
  253.       (if (re-search-backward begin-re (point-min) t) ; \beginmaxima
  254.             (setq found (point))))
  255.     (save-excursion
  256.       (if (and found
  257.                (re-search-backward end-re found t)) ; Intervening \endmaxima
  258.           (setq found nil)))
  259.     (save-excursion
  260.       (if (and found
  261.                (re-search-forward end-re (point-max) t)) ;\endmaxima
  262.           (setq found (point))))
  263.     (save-excursion
  264.         (if (and found 
  265.                 (re-search-forward begin-re found t)) ; Intervening \beginmaxima
  266.             (setq found nil)))
  267.     (if found t nil)))
  268.  
  269. (defun emaxima-session-cell-p ()
  270.   "Non-nil if point is in a session cell."
  271.   (and
  272.    (emaxima-cell-p)
  273.    (save-excursion
  274.      (re-search-backward "^\\\\beginmaxima")
  275.      (looking-at "\\\\beginmaximasession"))))
  276.  
  277. (defun emaxima-noshow-cell-p ()
  278.   "Non-nil if point is in a cell."
  279.   (and
  280.    (emaxima-cell-p)
  281.    (save-excursion
  282.      (re-search-backward "^\\\\beginmaxima")
  283.      (looking-at "\\\\beginmaximanoshow"))))
  284.  
  285. (defun emaxima-standard-cell-p ()
  286.   (and
  287.    (emaxima-cell-p)
  288.    (not (emaxima-session-cell-p))
  289.    (not (emaxima-noshow-cell-p))))
  290.  
  291. (defun emaxima-init-cell-p ()
  292.   (and 
  293.    (emaxima-standard-cell-p)
  294.    (save-excursion
  295.      (re-search-backward "^\\\\beginmaxima")
  296.      (goto-char (match-end 0))
  297.      (looking-at "\\[\\* Initialization Cell \\*\\]"))))
  298.  
  299. (defun emaxima-package-cell-p ()
  300.   (and 
  301.    (emaxima-standard-cell-p)
  302.    (save-excursion
  303.      (re-search-backward "^\\\\beginmaxima")
  304.      (goto-char (match-end 0))
  305.      (if (looking-at "\\[\\* Initialization Cell \\*\\]")
  306.          (goto-char (match-end 0)))
  307.      (looking-at "<"))))
  308.      
  309.  
  310. ;;; Create the cells.
  311. (defun emaxima-new-standard-cell ()
  312.   "Insert cell in buffer."
  313.   (if (not (bolp))
  314.       (progn
  315.         (open-line 1)
  316.         (forward-line 1)))
  317.   (insert "\\beginmaxima\n\n\\endmaxima")
  318.   (unless (looking-at " *$")
  319.     (insert "\n")
  320.     (forward-line -1))
  321.   (beginning-of-line)
  322.   (previous-line 1))
  323.  
  324. (defun emaxima-new-session-cell ()
  325.   "Insert cell in buffer."
  326.   (if (not (bolp))
  327.       (progn
  328.         (open-line 1)
  329.         (forward-line 1)))
  330.   (insert "\\beginmaximasession\n\n\\endmaximasession")
  331.   (unless (looking-at " *$")
  332.     (insert "\n")
  333.     (forward-line -1))
  334.   (beginning-of-line)
  335.   (previous-line 1))
  336.  
  337. (defun emaxima-new-noshow-cell ()
  338.   "Insert cell in buffer."
  339.   (if (not (bolp))
  340.       (progn
  341.         (open-line 1)
  342.         (forward-line 1)))
  343.   (insert "\\beginmaximanoshow\n\n\\endmaximanoshow")
  344.   (unless (looking-at " *$")
  345.     (insert "\n")
  346.     (forward-line -1))
  347.   (beginning-of-line)
  348.   (previous-line 1))
  349.  
  350. (defun emaxima-create-standard-cell ()
  351.   "Insert standard cell in buffer."
  352.   (interactive)
  353.   (if (not (emaxima-cell-p))
  354.       (emaxima-new-standard-cell)
  355.     (if (emaxima-standard-cell-p)
  356.         (error "Currently in cell.")
  357.       (save-excursion
  358.         (re-search-backward "^\\\\beginmaxima")
  359.         (goto-char (match-end 0))
  360.         (if (emaxima-session-cell-p)
  361.             (progn
  362.               (delete-char 7)
  363.               (re-search-forward "^\\\\endmaxima")
  364.               (delete-char 7))
  365.           (delete-char 6)
  366.           (re-search-forward "^\\\\endmaxima")
  367.           (delete-char 6))))))
  368.  
  369. (defun emaxima-create-session-cell ()
  370.   "Insert session cell in buffer."
  371.   (interactive)
  372.   (if (not (emaxima-cell-p))
  373.       (emaxima-new-session-cell)
  374.     (if (emaxima-session-cell-p)
  375.         (error "Currently in cell.")
  376.       (if (emaxima-standard-cell-p)
  377.           (progn
  378.             (if (emaxima-init-cell-p)
  379.                 (error "Currently in initialization cell.")
  380.               (if (emaxima-package-cell-p)
  381.                   (error "Currently in package cell.")
  382.                 (save-excursion
  383.                   (re-search-backward "^\\\\beginmaxima")
  384.                   (goto-char (match-end 0))
  385.                   (insert "session")
  386.                   (re-search-forward "^\\\\endmaxima")
  387.                   (insert "session")))))
  388.         (save-excursion
  389.           (re-search-backward "^\\\\beginmaxima")
  390.           (goto-char (match-end 0))
  391.           (delete-char 6)
  392.           (insert "session")
  393.           (re-search-forward "^\\\\endmaxima")
  394.           (delete-char 6)
  395.           (insert "session"))))))
  396.  
  397. (defun emaxima-create-noshow-cell ()
  398.   "Insert noshow cell in buffer."
  399.   (interactive)
  400.   (if (not (emaxima-cell-p))
  401.       (emaxima-new-noshow-cell)
  402.     (if (emaxima-noshow-cell-p)
  403.         (error "Currently in cell.")
  404.       (if (emaxima-standard-cell-p)
  405.           (progn
  406.             (if (emaxima-init-cell-p)
  407.                 (error "Currently in initialization cell.")
  408.               (if (emaxima-package-cell-p)
  409.                   (error "Currently in package cell.")
  410.                 (save-excursion
  411.                   (re-search-backward "^\\\\beginmaxima")
  412.                   (goto-char (match-end 0))
  413.                   (insert "noshow")
  414.                   (re-search-forward "^\\\\endmaxima")
  415.                   (insert "noshow")))))
  416.         (save-excursion
  417.           (re-search-backward "^\\\\beginmaxima")
  418.           (goto-char (match-end 0))
  419.           (delete-char 7)
  420.           (insert "noshow")
  421.           (re-search-forward "^\\\\endmaxima")
  422.           (delete-char 7)
  423.           (insert "noshow"))))))
  424.  
  425. (defun emaxima-toggle-init ()
  426.   "Toggle initialization marker of cell containing point."
  427.   (interactive)
  428.   (if (emaxima-standard-cell-p)
  429.       (save-excursion
  430.         (re-search-backward "^\\\\beginmaxima")
  431.         (goto-char (match-end 0))
  432.         (if (looking-at "\\[\\* Initialization Cell \\*\\]")
  433.             (delete-region (match-beginning 0) (match-end 0))
  434.           (insert "[* Initialization Cell *]")))
  435.     (error "Not in (standard) Maxima cell")))
  436.  
  437. (defun emaxima-package-part ()
  438.   "Insert package marker for cell."
  439.   (interactive)
  440.   (if (emaxima-standard-cell-p)
  441.       (save-excursion
  442.         (let ((package (read-string "Package: " "...:")))
  443.           (re-search-backward "^\\\\beginmaxima")
  444.           (goto-char (match-end 0))
  445.           (insert (concat "<" package ">"))))
  446.     (message "Not in (standard) Maxima cell")))
  447.   
  448. ;;; Cell positions
  449.  
  450. (defun emaxima-cell-start ()
  451.   "Return position of start of cell containing point."
  452.   (let ((begin-re "^\\\\beginmaxima"))
  453.   (save-excursion
  454.     (if (not (looking-at begin-re))
  455.         (re-search-backward begin-re))
  456.     (forward-line 1)
  457.     (point))))
  458.  
  459. (defun emaxima-cell-end ()
  460.   "Return position of end of cell containing point."
  461.   (let ((end-re "^\\\\endmaxima"))
  462.     (save-excursion
  463.       (re-search-forward end-re)
  464.       (forward-line -1)
  465.       (end-of-line)
  466.       (point))))
  467.  
  468. (defun emaxima-previous-cell-start ()
  469.   "Get start of preceding cell.  If none, return current position."
  470.   (let ((cur-pos (point))
  471.         (start nil)
  472.         (begin-re "^\\\\beginmaxima")
  473.         (end-re "^\\\\endmaxima"))
  474.     (save-excursion
  475.       (if (not (re-search-backward end-re (point-min) t))
  476.           cur-pos
  477.         (if (emaxima-cell-p)
  478.             (progn
  479.               (re-search-backward begin-re)
  480.               (forward-line 1)
  481.               (point))
  482.           cur-pos)))))
  483.               
  484. (defun emaxima-next-cell-start ()
  485.   "Get start of next cell.  If none, return current position."
  486.   (let ((cur-pos (point))
  487.         (start nil)
  488.         (begin-re "^\\\\beginmaxima")
  489.         (end-re "^\\\\endmaxima"))
  490.     (save-excursion
  491.       (if (re-search-forward begin-re (point-max) t)
  492.           (progn
  493.             (if (not (emaxima-cell-p))
  494.                 cur-pos)
  495.             (forward-line 1)
  496.             (point))
  497.         cur-pos))))
  498.  
  499. ;;; Cell motion
  500.  
  501. (defun emaxima-forward-cell ()
  502.   "Move to next cell."
  503.   (interactive)
  504.     (let ((cur-pos (point))
  505.           (cell-pos (point-max))
  506.           new-pos)
  507.         (setq new-pos (emaxima-next-cell-start))
  508.         (if (not (equal new-pos cur-pos))
  509.             (if (> new-pos cell-pos)
  510.                 nil
  511.               (setq cell-pos new-pos)))
  512.       (if (equal cell-pos (point-max))
  513.           nil; No more cells
  514.         (goto-char cell-pos))))
  515.  
  516. (defun emaxima-backward-cell ()
  517.   "Move to previous cell."
  518.   (interactive)
  519.     (let ((cur-pos (point))
  520.           (cell-pos (point-min))
  521.           new-pos)
  522.         (setq new-pos (emaxima-previous-cell-start))
  523.         (if (not (equal new-pos cur-pos))
  524.             (if (< new-pos cell-pos)
  525.                 nil
  526.               (setq cell-pos new-pos)))
  527.       (if (equal cell-pos (point-min))
  528.           nil ; No more cells
  529.         (goto-char cell-pos))))
  530.  
  531. ;;; Output related functions
  532.         
  533. (defun emaxima-delete-output ()
  534.   "Delete current output (if any).  Assumes point in cell.
  535. Output assumed to follow input, separated by a emaxima-output-marker line.
  536. Input *may* contain blank lines."
  537.   (interactive)
  538.   (let ((out-start (emaxima-output-p)))
  539.     (if out-start
  540.         (delete-region out-start (emaxima-cell-end))
  541.       t)))
  542.  
  543. (defun emaxima-output-p ()
  544.   "Return start of output text if present, else return nil.  Assumes
  545. point in cell.  Output assumed to follow input, separated by a
  546. \maximaoutput, \maximatexoutput, \maximasession, or \maximatexsession."
  547.   (save-excursion
  548.     (goto-char (emaxima-cell-start))
  549.     (if (re-search-forward "^\\\\maxima"
  550.          (emaxima-cell-end) t)
  551.         (progn
  552.           (forward-line -1)
  553.           (end-of-line)
  554.           (point))
  555.       nil)))
  556.  
  557. ;;; @@ EMaxima functions for package assembly
  558.  
  559. (defun emaxima-replace-assoc (alist key val)
  560.   "Replace ALIST KEY VALUE, if KEY present, else add KEY VALUE.
  561. Return modified alist."
  562.   (if (assoc key alist)
  563.       (setcdr (assoc key alist) val)
  564.     (setcdr alist (cons (cons key val) (cdr alist))))
  565.   alist)
  566.  
  567. (defun emaxima-assemble (arg)
  568.  "Assemble package (see emaxima-assemble-package), or, with C-u prefix,
  569. assemble references within a cell (see emaxima-assemble-cell)."
  570.   (interactive "P")
  571.   (if arg
  572.       (emaxima-assemble-package)
  573.     (emaxima-assemble-cell)))
  574.  
  575. (defun emaxima-assemble-cell (&optional delete)
  576.   "Assemble references in cell to file with unique name.  The buffer used to
  577. write the file is not deleted, unless optional DELETE is non-nil.
  578. Return the filename."
  579.  
  580.   ;; Here is how this function works:
  581.  
  582.   ;; The text of the cell is written to a buffer with key `file:part'.  Then
  583.   ;; the number of references in the cell is counted.  If the number of
  584.   ;; references in the cell is less than emaxima-max-references, then the cell
  585.   ;; references are resolved by successive calls to emaxima-dereference-buffer
  586.   ;; which collates the text for cell references as needed, using
  587.   ;; emaxima-collate-cells.  If the number of references is equal to or
  588.   ;; greater than emaxima-max-references, then all cells in the document
  589.   ;; correpsonding to the current cell type and filename are collated into
  590.   ;; buffers, using emaxima-collate-cells, and then the all cell references
  591.   ;; are are resolved by successive calls to emaxima-dereference-buffer.
  592.  
  593.   ;; The global `emaxima-buffer-alist' associates buffer names with keys.
  594.   ;; Buffer names are unique.  The names of all buffers are constructed with
  595.   ;; `maxima-make-temp-name' and are unique.  All buffers except possibly the
  596.   ;; cell-buffer are deleted on exit.
  597.  
  598.   (interactive)
  599.   (let ((home-buffer (current-buffer))
  600.         files parts file part 
  601.         ref-count
  602.         cell-key cell-buffer tmp-alist tmp-buffer)
  603.     (if (not (emaxima-cell-p)) (error "Not in a cell"))
  604.     (if (not (emaxima-reference-p)) (error "Cell contains no references"))
  605.     (save-excursion
  606.       (goto-char (emaxima-cell-start))
  607.       (forward-line -1)
  608.       (if (not (looking-at "^\\\\beginmaxima.*<.*:.*>"))
  609.           (error "Cell is not marked"))
  610.  
  611.       (setq emaxima-error-point (point))
  612.       (if emaxima-abbreviations-allowed
  613.           (unwind-protect ; In case filename errors
  614.               ;; This can take some seconds
  615.               (progn
  616.                 (message "Getting filenames...")
  617.                 (setq files (emaxima-get-filenames))
  618.                 (message "")
  619.                 )
  620.             (goto-char emaxima-error-point)))
  621.  
  622.       (setq file (emaxima-get-filename files))
  623.       (if (not file) (error "Ambiguous filename"))
  624.  
  625.       (if emaxima-abbreviations-allowed
  626.           ;; This can take several seconds for a document with many cells
  627.           (progn
  628.             (message "Getting partnames")
  629.             (setq parts (emaxima-get-partnames file files))
  630.             (message "")
  631.             ))
  632.  
  633.       (setq part (emaxima-get-partname parts))
  634.       (if  (not part) (error "Ambiguous partname"))
  635.  
  636.       ) ; save-excursion
  637.  
  638.     (setq cell-key (concat file ":"))
  639.     (if (not (equal part "")) (setq cell-key (concat cell-key part)))
  640.     (message "Assembling `%s' ..." cell-key) ; (sleep-for 1)
  641.     (setq cell-buffer (maxima-make-temp-name))
  642.     (setq emaxima-buffer-alist (list (cons cell-key cell-buffer)))
  643.     (unwind-protect
  644.         (save-excursion
  645.           (emaxima-append-cell-to-buffer cell-buffer)
  646.           (setq emaxima-source-buffer (current-buffer)) ; Collate from here
  647.  
  648.           (if (< (emaxima-reference-count cell-buffer) emaxima-max-references)
  649.               ;; Build reference buffers as needed
  650.                 (while (emaxima-dereference-buffer cell-key files parts nil))
  651.             ;; Prebuild all reference buffers
  652.             (emaxima-collate-cells file part files parts nil)
  653.             (while (emaxima-dereference-buffer cell-key files parts nil nil))
  654.             )
  655.           (set-buffer cell-buffer)
  656.           (write-file (concat emaxima-temp-dir cell-buffer))
  657.           (set-buffer home-buffer)
  658.           )
  659.       ;; unwind-protect forms: deleted cell buffers
  660.       (setq tmp-alist emaxima-buffer-alist)
  661.       (while (setq tmp-buffer (cdr (car tmp-alist)))
  662.         (setq tmp-alist (cdr tmp-alist))
  663.         (condition-case nil ; In case buffer not actually created
  664.             (if (and (not delete) (equal tmp-buffer cell-buffer))
  665.                 nil ; Don't delete the assembly buffer
  666.               (kill-buffer tmp-buffer))
  667.           (error nil)))
  668.       ) ; unwind-protect
  669.     (message "`%s' assembled in file `%s%s'" 
  670.          cell-key emaxima-temp-dir cell-buffer)
  671.     (concat emaxima-temp-dir cell-buffer)))
  672.  
  673. (defun emaxima-assemble-package (&optional file overwrite)
  674.   "Assemble text into a package buffer and write that buffer to a file.
  675. The buffer is *not* deleted.  Return the filename.
  676.  
  677. Optional arguments (useful for batch processing):
  678.  
  679. FILE package filename;
  680. OVERWRITE, if not nil package filename buffer will be overwritten 
  681. without asking."
  682.  
  683.   ;; Here is how this function works:
  684.  
  685.   ;; The entire buffer is scanned for marked cells matching TYPE and FILE and
  686.   ;; these are collated by `file' and `part' into buffers with keys
  687.   ;; `file:part' and, for `part' = "" (a package cell), into a buffer with key
  688.   ;; `FILE'.
  689.  
  690.   ;; Once the cell buffers have been created, then all cell references in the
  691.   ;; package buffer, with key `FILE', are replaced by the contents of the
  692.   ;; corresponding buffers with keys `file:part', by successive calls to
  693.   ;; emaxima-dereference-buffer.
  694.  
  695.   ;; The global `emaxima-buffer-alist' associates buffer names with keys.
  696.   ;; Buffer names are unique.  The names of all buffers are constructed with
  697.   ;; `maxima-make-temp-name' and are unique.    All buffers
  698.   ;; except the package buffer `FILE' are deleted on exit.
  699.  
  700.   (interactive)
  701.   (let ((home-buffer (current-buffer))
  702.         files parts prompt
  703.         tmp-buffer tmp-alist file-buffer
  704.         )
  705.  
  706.     (if (not file)
  707.         ;; If file has not been specifed, prompt
  708.         (progn
  709.               ;; Get default file from cell label, if any
  710.               (save-excursion
  711.                 (goto-char (emaxima-cell-start))
  712.                 (forward-line -1)
  713.                 (if (looking-at "^\\\\beginmaxima.*<.*:.*>")
  714.                     (progn
  715.                       (setq emaxima-error-point (point))
  716.                       (unwind-protect ; In case filename errors
  717.                           (if emaxima-abbreviations-allowed
  718.                               ;; This can take some seconds
  719.                               (progn
  720.                                 (message "Getting filenames...")
  721.                                 (if (not (setq files (emaxima-get-filenames)))
  722.                                     (error 
  723.                                        "No complete package filenames found"))
  724.                                 (message "")
  725.                                 ))
  726.                         (goto-char emaxima-error-point))
  727.                       (setq file (emaxima-get-filename files)))))
  728.           (setq file (read-from-minibuffer "Package file: " file))
  729.           (if (or (not file) (equal file "")) (error "No file specified"))))
  730.  
  731.     (if (not overwrite)
  732.         (if (file-exists-p file)
  733.             (progn
  734.               (setq prompt (concat
  735.                             "Package file `"
  736.                             file
  737.                             "' exists. Overwrite it ? "))
  738.               (if (not (y-or-n-p prompt))
  739.                   (error "Package assembly cancelled")))))
  740.     
  741.     (if (get-buffer file) (kill-buffer file))
  742.  
  743.     (if emaxima-abbreviations-allowed
  744.         ;; This can take several seconds for a document with many cells
  745.         (progn
  746.           (message "Getting partnames...")
  747.           (setq parts (emaxima-get-partnames file files))
  748.           (message "")))
  749.  
  750.     (message "Assembling package `%s' ..." file) ;(sleep-for 1)
  751.  
  752.     ;; Set where assembly will occur
  753.     (setq file-buffer (maxima-make-temp-name))
  754.     (setq emaxima-buffer-alist (list (cons file file-buffer)))
  755.  
  756.     (unwind-protect ; So buffer can be deleted even if errors or abort
  757.         (progn
  758.           (setq emaxima-source-buffer (current-buffer)) ; Collate from here
  759.           (emaxima-collate-cells file nil files parts nil)
  760.           (or (get-buffer (cdr (assoc file emaxima-buffer-alist)))
  761.               (error "No `%s' cell `%s:' found" file))
  762.           
  763.           ;; OK, here we go:  Recursively dereference the cell buffer:
  764.           (while (emaxima-dereference-buffer file files parts))
  765.  
  766.           (set-buffer file-buffer)
  767.           (write-file file)
  768.           (set-buffer home-buffer))
  769.       ;; unwind-protect tail:  Delete part files
  770.       (setq tmp-alist emaxima-buffer-alist)
  771.       (while (setq tmp-buffer (cdr (car tmp-alist)))
  772.         (setq tmp-alist (cdr tmp-alist))
  773.         (condition-case nil ; In case buffer not actually created
  774.             (if (equal tmp-buffer file-buffer)
  775.                 nil ; Don't delete the package buffer
  776.               (kill-buffer tmp-buffer))
  777.           (error nil)))
  778.       ) ; unwind-protect
  779.     (message "Package `%s' assembled" file)
  780. ;    file
  781.     (switch-to-buffer-other-window file)))
  782.  
  783. (defun emaxima-reference-count (buffer)
  784.   "Return the number of references in BUFFER."
  785.   (let ((count 0)
  786.         (home-buffer (current-buffer)))
  787.     (save-excursion
  788.           (set-buffer buffer)
  789.           (goto-char (point-min))
  790.           (while (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (point-max) t)
  791.             (setq count (+ count 1)))
  792.           (set-buffer home-buffer))
  793.     count))
  794.  
  795. (defun emaxima-append-cell-to-buffer (buffer)
  796.   "Append text of cell containing point to BUFFER.
  797. Create BUFFER if it does not exist."
  798.   (if (not (emaxima-cell-p))
  799.       (error "Not in a cell.")
  800.     (let ((home-buffer (current-buffer))
  801.           (start (emaxima-cell-start))
  802.           end)
  803.       (save-excursion
  804.     (goto-char start)
  805.     (beginning-of-line)
  806.         (while (looking-at "^ *$") (forward-line 1))
  807.     (setq start (point))
  808.     (if (not (setq end (emaxima-output-p)))
  809.         (progn
  810.           (goto-char (emaxima-cell-end))
  811.           (while (looking-at "^ *$") (forward-line -1))
  812.           (end-of-line)
  813.           (setq end (point)))
  814.       (progn
  815.         (goto-char end)
  816.         (while (looking-at "^ *$") (forward-line -1))
  817.         (end-of-line)
  818.         (setq end (point))))
  819.         (set-buffer (get-buffer-create buffer))
  820.         (goto-char (point-max))
  821.         (insert-buffer-substring home-buffer start end)
  822.         (insert "\n")))))
  823.  
  824. (defun emaxima-collate-cells (file part files parts &optional single)
  825.  
  826.   "Assemble cells marked with filename FILE in buffers with keys
  827. `file:part' or, for part = null string (package cells), with key `file'.  The
  828. names of all buffers are constructed with `maxima-make-temp-name' and are
  829. unique.  If PART is non-nil then do not collate cells with keys `FILE:PART'
  830. and `FILE' (package cells).  Use FILES and PARTS for name completion \(see
  831. `emaxima-get-filename' and `emaxima-get-partname'\).  If optional SINGLE is
  832. non-nil, then collate just cells `FILE:PART' (PART must be non-nil).
  833.  
  834. The global `emaxima-buffer-alist' associates buffer names with keys.  It must
  835. be initialized, typically with the buffer for key `FILE' or `FILE:PART',
  836. according to whether PART is nil or not."
  837.  
  838.   (let ((home-buffer (current-buffer))
  839.         this-part this-file key)
  840.     (unwind-protect ; For error location
  841.         (setq emaxima-error-point (point)) ; Go here if no error
  842.         (progn
  843.  
  844.           ;; Scan buffer to construct buffers for all `file:part'
  845.           (save-excursion
  846.             (set-buffer emaxima-source-buffer) ; Collate from here
  847.             (goto-char (point-min))
  848.             (while (emaxima-forward-cell)
  849.                    ;; We have a cell of the right type
  850.                 (forward-line -1) ; Move to \begin{...
  851.                 (if (not (looking-at "^\\\\beginmaxima.*<.*:.*>"))
  852.                     (forward-line 1) ; So we go to next cell next time through
  853.  
  854.                   ;; We have a marked cell
  855.                   (setq this-file (emaxima-get-filename files))
  856.                   (cond
  857.                    ((not this-file)
  858.                     (setq emaxima-error-point (point))
  859.                     (error "Ambiguous filename"))
  860.                    ((not (equal file this-file))
  861.                     (forward-line 1)) ; So we go to next cell next time through
  862.                    (t
  863.  
  864.                     ;; We have a cell of the right package filename
  865.                     (setq this-part (emaxima-get-partname parts))
  866.                     (cond
  867.                      ((not this-part)
  868.                       (setq emaxima-error-point (point))
  869.                       (error "Ambiguous partname"))
  870.                      ((and single (not (equal this-part part)))
  871.                       (forward-line 1));Do only `file:part' for SINGLE non-nil
  872.                      ((and part (equal this-part ""))
  873.                       (forward-line 1));Cell assembly, 
  874.                                        ;ignore package cell `FILE:'
  875.                      ((and (not single) (equal this-part part))
  876.                       (forward-line 1));Cell assembly, ignore cell `FILE:PART'
  877.                      (t
  878.  
  879.                       ;; We have a cell with a valid partname
  880.                       (forward-line 1) ; Move into cell
  881.                       (if (equal this-part "")
  882.                           (setq key file)
  883.                         (setq key (concat file ":" this-part)))
  884.                       (or
  885.                        (assoc key emaxima-buffer-alist) ; buffer already created
  886.                        (emaxima-replace-assoc
  887.                         emaxima-buffer-alist
  888.                         key (maxima-make-temp-name)))
  889.  
  890.                       ;; Append cell contents to its buffer
  891.                       (emaxima-append-cell-to-buffer
  892.                        (cdr (assoc key emaxima-buffer-alist)))
  893.                       
  894.                       ) ; t on valid partname
  895.                      ) ; cond on partname
  896.                     ) ; t on right filename (package)
  897.                    ) ; cond on filename
  898.                   ) ; if a marked cell
  899.               ) ; while still cells to process
  900.             (set-buffer home-buffer)
  901.             ) ; save excursion
  902.           ) ; progn of unwind-protect body
  903.       
  904.       ;; unwind-protect tail:  Delete part files
  905.       (goto-char emaxima-error-point))))
  906.  
  907. (defun emaxima-dereference-buffer (key files parts &optional noinit)
  908.   "Resolve all references in buffer corresponding to KEY in alist
  909. emaxima-buffer-alist, using FILES and PARTS for name completion.  If optional
  910. NOINIT is nil, initialize global variable `emaxima-dereference-path' with KEY.
  911. If NOINIT is non-nil, add KEY to `emaxima-dereference-path'. 
  912. then references are collated in buffers and added to emaxima-buffer-alist if
  913. necessary.  Use `emaxima-dereference-path' to check for self-reference and
  914. report error if detected,"
  915.   (let ((ref-found nil)
  916.         (home-buffer (current-buffer))
  917.         path-to-here
  918.         ref-indent ref-key ref-buffer
  919.         (key-buffer (cdr (assoc key emaxima-buffer-alist)))
  920.         file part
  921.         re-found
  922.         )
  923.     (or key-buffer (error "No cell `%s'" key))
  924.     (set-buffer key-buffer)
  925.     (goto-char (point-min))
  926.     (if noinit
  927.         t
  928.       (setq noinit t)
  929.       (setq emaxima-dereference-path (list key))
  930.       )
  931.     (setq path-to-here emaxima-dereference-path)
  932.     (while (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (point-max) t)
  933.       (setq re-found 1)
  934.       (beginning-of-line)
  935.       (setq ref-indent (emaxima-get-reference-indentation))
  936.       (setq file (emaxima-get-filename files))
  937.       (setq part (emaxima-get-partname parts))
  938.       (setq ref-key (concat file ":" part))
  939.       (if (emaxima-string-mem ref-key path-to-here)
  940.             (emaxima-dereference-error (cons ref-key path-to-here)))
  941.       (setq emaxima-dereference-path (cons ref-key path-to-here))
  942.       (if (not (assoc ref-key emaxima-buffer-alist))
  943.           ;; Construct buffer on the fly
  944.           (progn
  945.             (setq ref-buffer (maxima-make-temp-name))
  946.             (emaxima-replace-assoc emaxima-buffer-alist ref-key ref-buffer)
  947.             (emaxima-collate-cells file part files parts t)
  948.             )
  949.         (setq ref-buffer (cdr (assoc ref-key emaxima-buffer-alist)))
  950.         )
  951.       (while (emaxima-dereference-buffer ref-key files parts noinit))
  952.       (kill-line 1) ; Remove reference line
  953.       (insert-buffer ref-buffer)
  954.       (let ((indent-start (point))
  955.             indent-end)
  956.         (exchange-point-and-mark)
  957.         (setq indent-end (point))
  958.         (exchange-point-and-mark)
  959.         (if ref-indent (indent-rigidly indent-start indent-end ref-indent))))
  960.     (setq emaxima-dereference-path path-to-here)
  961.     (set-buffer home-buffer)
  962.     ref-found))
  963.  
  964. (defun emaxima-dereference-error (path)
  965.   "Report package self-reference error, in PATH"
  966.   (let ((cell (car path))
  967.         (home-buffer (current-buffer))
  968.         to-cell from-cell)
  969.     (setq to-cell cell)
  970.     (with-output-to-temp-buffer "*Help*" (message ""))
  971.     (pop-to-buffer "*Help*")
  972.     (insert "Self-reference detected assembling Maxima/TeX cell\n\n")
  973.     (insert (concat "\t\t" to-cell "\n\n"))
  974.     (insert "Here is how the self-reference happened:\n\n")
  975.     (setq path (reverse path))
  976.     (setq from-cell (car path))
  977.     (insert (concat "\t" from-cell "\n"))
  978.     (while (setq path (cdr path))
  979.       (setq to-cell (car path))
  980.       (if (equal cell to-cell)
  981.           (insert (concat " !!! ->\t   -->\t" to-cell "\n"))
  982.         (insert (concat "\t   -->\t" to-cell "\n")))
  983.       (setq from-cell to-cell)
  984.       )
  985.     (pop-to-buffer home-buffer)
  986.     (error "Self-reference detected")))
  987.  
  988. (defun emaxima-get-reference-indentation ()
  989.   "Return indentation of reference on current line.
  990. Line assumed tabified."
  991.   (let (start end)
  992.     (save-excursion
  993.       (beginning-of-line)
  994.       (setq start (point))
  995.       (search-forward "<")
  996.       (untabify start (point))
  997.       (setq end (point))
  998.       (beginning-of-line)
  999.       (tabify (point) end)
  1000.       (- end start 1))))
  1001.  
  1002. (defun emaxima-insert-complete-name ()
  1003.   "Insert complete name in buffer for cell.
  1004. Return t if successful, else nil."
  1005.   (interactive)
  1006.   (let ((here (point))
  1007.         start end name text files parts
  1008.         )
  1009.     (save-excursion
  1010.       (beginning-of-line)
  1011.       (cond
  1012.        ((and ; partname
  1013.          (or
  1014.           (re-search-forward "^\\\\beginmaxima<.*:[^\t]*" here t)
  1015.           (re-search-forward "^[ \t]*<.*:[^\t]*" here t))
  1016.          (equal here (point)))
  1017.  
  1018.         ;; This can take a second or two
  1019.         (message "Getting filenames...")
  1020.         (if (not (setq files (emaxima-get-filenames)))
  1021.             (error "No package filenames in document"))
  1022.         (message "")
  1023.  
  1024.         (search-backward "<")
  1025.         (forward-char 1)
  1026.         (setq start (point))
  1027.         (search-forward ":")
  1028.         (forward-char -1)
  1029.         (setq text (buffer-substring start (point)))
  1030.         (if (not (setq name (emaxima-complete-name text files)))
  1031.             (error "No matching package filename found"))
  1032.  
  1033.         ;; This can take several seconds for a document with many cells
  1034.         (message "Getting partnames")
  1035.         (setq parts (emaxima-get-partnames name files))
  1036.         (message "")
  1037.  
  1038.         (forward-char 1)
  1039.         (setq start (point)) ; New start, for partname deletion
  1040.         (setq text (buffer-substring (point) here))
  1041.         (if (not (setq name (emaxima-complete-name
  1042.                              (concat text "...")
  1043.                              parts)))
  1044.             (error "No matching package partname found"))
  1045.         (cond
  1046.          ((equal t name) ; Text is complete
  1047.           (setq name text))
  1048.          ((equal t (try-completion name parts)))
  1049.          (t ; Else, get completion
  1050.           (setq name
  1051.                 (completing-read
  1052.                  "Partname (<space> to see partnames): "
  1053.                  parts nil t name))
  1054.           )
  1055.          ) ; cond: what kind of partname completion was done
  1056.         (delete-region start here)
  1057.         (insert (concat name ">"))) ; End of partname completion
  1058.        ((and ; filename
  1059.          (or (re-search-forward "^\\\\beginmaxima<[^ \t]*" here t)
  1060.              (re-search-forward "^[ \t]*<[^ \t]*" here t))
  1061.          (equal here (point)))
  1062.  
  1063.         ;; This can take a second or two
  1064.         (message "Getting filenames...")
  1065.         (if (not (setq files (emaxima-get-filenames)))
  1066.             (error "No package filenames in document"))
  1067.         (message "")
  1068.  
  1069.         (re-search-backward "<")
  1070.         (forward-char 1)
  1071.         (setq start (point))
  1072.         (setq text (buffer-substring start here))
  1073.         (if (not (setq name (emaxima-complete-name
  1074.                              (concat text "...") ; completion form
  1075.                              files)))
  1076.             (error "No matching package filename found"))
  1077.         (cond
  1078.          ((equal t name) ; Text is complete
  1079.           (setq name text))
  1080.          ((equal t (try-completion name files)))
  1081.          (t ; Else, get completion
  1082.           (setq name
  1083.                 (completing-read
  1084.                  "Filename (<space> to see filenames): "
  1085.                  files nil t name))
  1086.           (if (equal "" name) (error ""))))
  1087.         (delete-region start here)
  1088.         (insert (concat name ":")))
  1089.        (t
  1090.         ;;(error "Nothing to complete")
  1091.         nil))) ; save-excursion
  1092.     (if (not name)
  1093.         nil
  1094.       (goto-char (+ (point) (length name) 1))
  1095.       t)))
  1096.  
  1097. (defun emaxima-get-filenames ()
  1098.   "Return alist of package filenames for cells."
  1099.   (let (file files)
  1100.     (save-excursion
  1101.       (goto-char (point-min))
  1102.       (while (emaxima-forward-cell)
  1103.           (forward-line -1)
  1104.           (if (not (looking-at (concat "^\\\\beginmaxima.*<.*>")))
  1105.               (forward-line 1) ; Cell not marked.  Get set for next one
  1106.             (if (setq file (emaxima-get-filename)) ; Only unabbreviated names
  1107.                 (if files
  1108.                     (if (assoc file files)
  1109.                         nil ; already only
  1110.                       (setq files (cons (list file) files))) ; Add to alist
  1111.                   (setq files (list (list file))))) ; Start alist
  1112.             (forward-line 1)
  1113.             ) ; if a marked cell
  1114.         ) ; while cell to look at
  1115.       ) ; save-excursion
  1116.     files))
  1117.  
  1118. (defun emaxima-complete-name (text alist &optional exact)
  1119.   "Get full name corresponding to TEXT.
  1120. If text is a string ending in `...',
  1121. then the substring preceding the `...' is used with try-completion on ALIST.
  1122. An exact match is required if optional EXACT is t.
  1123. If text is just `...' and alist is length 1, then the car of its single element
  1124. is returned.
  1125. Oherwise nil is returned."
  1126.   (let (name try-name)
  1127.     (if (not (string-match "\\(\\.\\.\\.$\\)" text))
  1128.         (setq name text) ; don't do completion on full names
  1129.       (if (and
  1130.            (eq 0 (match-beginning 1)) ; just "..."
  1131.            (eq 1 (length alist))) ; a single package filename
  1132.           (setq name (car (car alist)))
  1133.         (setq try-name (substring text 0 (match-beginning 1)))
  1134.         (setq name (try-completion try-name alist)))
  1135.       (cond
  1136.        ((equal t name)
  1137.         (setq name try-name))
  1138.        ((and
  1139.          exact
  1140.          (not (equal t (try-completion name alist))))
  1141.         (setq name nil)))) ; Not an exact match, so error
  1142.     name))
  1143.  
  1144. (defun emaxima-get-partnames (file files)
  1145.   "Return alist of partnames for package FILE, using FILES for
  1146. filename completion."
  1147.   (let (cell-end cell-file part parts)
  1148.     (setq emaxima-error-point (point))
  1149.     (unwind-protect
  1150.         (save-excursion
  1151.           (goto-char (point-min))
  1152.           (while (emaxima-forward-cell)
  1153.               (setq cell-end (emaxima-cell-end))
  1154.               (forward-line -1)
  1155.               (if (not (looking-at
  1156.                        "^\\\\beginmaxima.*<[^:].*:.*>"))
  1157.                   (forward-line 1) ; Not a marked cell
  1158.                 (setq cell-file (emaxima-get-filename files))
  1159.                 (if (not (equal file cell-file))
  1160.                     (forward-line 1) ; Wrong file
  1161.                   (while (and
  1162.                           (<= (point) cell-end)
  1163.                           (or
  1164.                            (re-search-forward
  1165.                             "^\\\\beginmaxima.*<[^:].*:.*>" cell-end t)
  1166.                            (re-search-forward
  1167.                             "^ *\t*<[^:].*:.*>" cell-end t)))
  1168.                     (beginning-of-line) ; We have a filename-partname reference
  1169.                     (if (not (setq file (emaxima-get-filename files)))
  1170.                         (progn
  1171.                           (setq emaxima-error-point (point))
  1172.                           (error "Ambiguous filename")))
  1173.                     (if (not (equal cell-file file))
  1174.                         (progn
  1175.                           (setq emaxima-error-point (point))
  1176.                           (error "Reference must match cell filename: `%s'"
  1177.                                  cell-file)))
  1178.                     (setq part (emaxima-get-partname))
  1179.                     (if (not part)
  1180.                         nil ; Need full (unabbreviated) parts only, for alist
  1181.                       (if parts ; Update alist
  1182.                           (if (or
  1183.                                (equal part "")
  1184.                                (emaxima-string-mem part parts))
  1185.                               nil; already on list
  1186.                             (setq parts (append (list part) parts))) 
  1187.                     ; Add to alist
  1188.                         (if (not (equal part ""))
  1189.                             (setq parts (list part)))) ; Create alist
  1190.                       ) ; if an unabbreviated part                    
  1191.                     (forward-line 1)
  1192.                     ) ; while references to process in this cell
  1193.                   ) ; if a marked cell of this FILE
  1194.                 ) ; if a marked cell
  1195.             ) ; while cells to process
  1196.           ); save-excursion
  1197.       (goto-char emaxima-error-point) ; unwind-protect form
  1198.       ) ; unwind-protect
  1199.     (setq parts (mapcar 'list parts)) ; Make list into an alist
  1200.     parts))
  1201.  
  1202. (defun emaxima-get-filename (&optional alist)
  1203.   "Get filename in package reference on current line.
  1204. If optional ALIST is supplied, use it for name completion.
  1205. Return nil if no name or error in name."
  1206.   (let ((match-re "\\(<\\)[^:]*\\(:\\)")
  1207.         (abbrev-re "\\.\\.\\.")
  1208.         beg text)
  1209.     (save-excursion
  1210.       (beginning-of-line)
  1211.       (setq beg (point))
  1212.       (end-of-line)
  1213.       (setq text (buffer-substring beg (point)))
  1214.       (string-match match-re text)
  1215.       (setq text 
  1216.         (substring text (+ 1 (match-beginning 1)) (+ -1 (match-end 2)))))
  1217.     (if alist
  1218.         (emaxima-complete-name text alist t)
  1219.       (if (string-match abbrev-re text)
  1220.           (if emaxima-abbreviations-allowed
  1221.               nil
  1222.             (setq emaxima-error-point (point))
  1223.         (error 
  1224.   "Set emaxima-abbreviations-allowed (M-x set-variable) to use abbreviations")
  1225.             )
  1226.         text))))
  1227.  
  1228. (defun emaxima-get-partname (&optional alist)
  1229.   "Get partname in package reference on current line.
  1230. If optional ALIST is supplied, use it for name completion.
  1231. Return nil if no name or error in name."
  1232.   (let ((match-re "\\(:\\)\\([^>]*\\)")
  1233.         (abbrev-re "\\.\\.\\.")
  1234.         beg text)
  1235.     (save-excursion
  1236.       (beginning-of-line)
  1237.       (setq beg (point))
  1238.       (end-of-line)
  1239.       (setq text (buffer-substring beg (point)))
  1240.       (string-match match-re text)
  1241.       (setq text (substring text (+ 1 (match-beginning 1)) (match-end 2))))
  1242.     (if alist
  1243.         (emaxima-complete-name text alist t)
  1244.       (if (string-match abbrev-re text)
  1245.           (if emaxima-abbreviations-allowed
  1246.               nil
  1247.             (setq emaxima-error-point (point))
  1248.         (error 
  1249.    "Set emaxima-abbreviations-allowed (M-x set-variable) to use abbreviations")
  1250.             )
  1251.         text))))
  1252.  
  1253. (defun emaxima-string-mem (element list) ; memq doesn't work for strings
  1254.   "Returns t if string ELEMENT is in LIST of strings, else returns nil."
  1255.   (let (try
  1256.         (found nil))
  1257.     (while (and (setq try (car list)) (not found))
  1258.       (setq list (cdr list))
  1259.       (if (equal element try)
  1260.           (setq found t)))
  1261.     found))
  1262.  
  1263. (defun emaxima-reference-p ()
  1264.   "Return t if cell contains a cell reference, else retrun nil."
  1265.   (save-excursion
  1266.     (goto-char (emaxima-cell-start))
  1267.     (if (re-search-forward "^ *\t*<[^:].*:[^>].*>$" (emaxima-cell-end) t)
  1268.         t
  1269.       nil)))
  1270.  
  1271. ;;; Cell evaluation
  1272. ;;; Get information about the cell input and output
  1273.  
  1274. (defun emaxima-get-cell-contents ()
  1275.   "Return the cell contents as a string."
  1276.   (if (not (emaxima-cell-p))
  1277.       (message "Not in Maxima cell"))
  1278.   (let ((home-buffer (current-buffer))
  1279.         assembled-file start end)
  1280.     (if (emaxima-reference-p)
  1281.           (save-excursion
  1282.             (widen) ; So cell references will be found
  1283.             (set-buffer (find-file-noselect
  1284.                          (emaxima-assemble-cell t)))
  1285.             (buffer-substring-no-properties (point-min) (point-max)))
  1286.       (save-excursion
  1287.     (goto-char (emaxima-cell-start))
  1288.         ;; Now I want to skip over any blank lines at the beginning of the cell
  1289.     (beginning-of-line)
  1290.     (while (looking-at "^ *$") (forward-line 1))
  1291.     (setq start (point))
  1292.         ;; as well as at the end of the cell
  1293.     (if (not (setq end (emaxima-output-p)))
  1294.         (progn
  1295.           (goto-char (emaxima-cell-end))
  1296.           (while (looking-at "^ *$") (forward-line -1))
  1297.           (end-of-line)
  1298.           (setq end (point)))
  1299.       (progn
  1300.         (goto-char end)
  1301.         (while (looking-at "^ *$") (forward-line -1))
  1302.         (end-of-line)
  1303.         (setq end (point)))))
  1304.       (buffer-substring-no-properties start end))))
  1305.  
  1306. (defun emaxima-remove-end-spaces (string)
  1307.   "Remove the spaces and newlines at the ends of a string"
  1308.   (while (and (> (length string) 0) (string= (substring string 0 1) " "))
  1309.     (setq string (substring string 1)))
  1310.   (while (and (> (length string) 0) (string= (substring string -1) " "))
  1311.     (setq string (substring string 0 -1)))
  1312.   (while (and (> (length string) 0) (string= (substring string 0 1) "\n"))
  1313.     (setq string (substring string 1)))
  1314.   (while (and (> (length string) 0) (string= (substring string -1) "\n"))
  1315.     (setq string (substring string 0 -1)))
  1316.   string)
  1317.  
  1318. (defun emaxima-insert-last-output-tex ()
  1319.   (let ((mb)
  1320.         (me)
  1321.         (ie)
  1322.         (out (emaxima-last-maxima-output)))
  1323.     (while (string-match "(E[0-9]+)" out)
  1324.       (setq mb (match-beginning 0))
  1325.       (setq me (match-end 0))
  1326.       (if (and
  1327.            (> mb 0)
  1328.            (string-match "[^ \n]" (substring out 0 mb)))
  1329.           (progn
  1330.             (insert "\\p ")
  1331.             (insert substring out 0 mb)
  1332.             (insert " \\\\\n")))
  1333.       (insert "\\E")
  1334.       (insert (substring out (+ mb 2) (- me 1)))
  1335.       (insert ". ")
  1336.       (setq out (emaxima-remove-end-spaces (substring out me)))
  1337.       (string-match "([DE][0-9]+)" out)
  1338.       (setq ie (match-beginning 0))
  1339.       (insert (substring out 0 ie))
  1340.       (forward-char -1)
  1341.       (while (looking-at "\n")
  1342.         (delete-char 1)
  1343.         (forward-char -1))
  1344.       (forward-char 1)
  1345.       (insert " \\\\\n")
  1346.       (setq out (substring out ie)))
  1347.     (if (string-match "(D[0-9]+)" out)
  1348.         (progn
  1349.           (setq mb (match-beginning 0))
  1350.           (setq me (match-end 0))
  1351.           (if (and
  1352.                (> mb 0)
  1353.                (string-match "[^ \n]" (substring out 0 mb)))
  1354.               (progn
  1355.                 (insert "\\p ")
  1356.                 (insert (substring out 0 mb))
  1357.                 (insert " \\\\\n")))
  1358.           (insert "\\D")
  1359.           (insert (substring out (+ mb 2) (- me 1)))
  1360.           (insert ".  ")
  1361.           (insert (substring out me))
  1362.           (forward-char -1)
  1363.           (if (looking-at "\n")
  1364.               (progn
  1365.                 (insert " \\\\")
  1366.                 (forward-char 1))
  1367.             (forward-char 1)
  1368.             (insert " \\\\\n")))
  1369.       (when (not (string= out ""))
  1370.         (insert "\\p  ")
  1371.         (insert out)
  1372.         (forward-char -1)
  1373.         (if (looking-at "\n")
  1374.             (progn
  1375.               (insert " \\\\")
  1376.               (forward-char 1))
  1377.           (forward-char 1)
  1378.           (insert " \\\\\n"))))))
  1379.  
  1380. (defun emaxima-insert-last-output-tex-noprompt ()
  1381.   (let ((out (emaxima-last-maxima-output))
  1382.         (me)
  1383.         (mb)
  1384.         (ie))
  1385.     (while (string-match "(E[0-9]+)" out)
  1386.       (setq mb (match-beginning 0))
  1387.       (setq me (match-end 0))
  1388.       (if (and
  1389.            (> mb 0)
  1390.            (string-match "[^ \n]" (substring out 0 mb)))
  1391.           (progn
  1392.             (insert "\\p ")
  1393.             (insert substring out 0 mb)
  1394.             (insert " \\\\\n")))
  1395.       (insert "\\E")
  1396.       (insert (substring out (+ mb 2) (- me 1)))
  1397.       (insert ". ")
  1398.       (setq out (emaxima-remove-end-spaces (substring out me)))
  1399.       (string-match "([DE][0-9]+)" out)
  1400.       (setq ie (match-beginning 0))
  1401.       (insert (substring out 0 ie))
  1402.       (forward-char -1)
  1403.       (while (looking-at "\n")
  1404.         (delete-char 1)
  1405.         (forward-char -1))
  1406.       (forward-char 1)
  1407.       (insert " \\\\\n")
  1408.       (setq out (substring out ie)))
  1409.     (if (string-match "(D[0-9]+)" out)
  1410.         (progn
  1411.           (if (> (match-beginning 0) 0)
  1412.               (progn
  1413.                 (insert "\\p ")
  1414.                 (insert (substring out 0 (match-beginning 0)))
  1415.                 (insert " \\\\\n")))
  1416.           (insert "$$")
  1417.           (insert "  ")
  1418.           (insert (substring out (match-end 0)))
  1419.           (forward-char -1)
  1420.           (if (looking-at "\n")
  1421.               (progn
  1422.                 (insert " $$")
  1423.                 (forward-char 1))
  1424.             (forward-char 1)
  1425.             (insert " $$\n")))
  1426.       (when (not (string= out ""))
  1427.         (insert "\\p  ")
  1428.         (insert out)
  1429.         (forward-char -1)
  1430.         (if (looking-at "\n")
  1431.             (progn
  1432.               (insert " \\\\")
  1433.               (forward-char 1))
  1434.           (forward-char 1)
  1435.           (insert " \\\\\n"))))))
  1436.  
  1437. (defun emaxima-last-input-prompt ()
  1438.   "Copy the last input-prompt from Maxima."
  1439.   (interactive)
  1440.   (let ((old-buffer (current-buffer))
  1441.         (maxima-buffer (get-buffer "*maxima*"))
  1442.         (prompt))
  1443.     (if (null maxima-buffer)
  1444.         (message "No Maxima output buffer")
  1445.       (set-buffer maxima-buffer)
  1446.       (save-excursion
  1447.     (goto-char (point-max))
  1448.         (if (maxima-finished-p)
  1449.             (re-search-backward inferior-maxima-prompt (point-min) nil 1)
  1450.           (re-search-backward inferior-maxima-prompt (point-min) nil 2))
  1451.         (setq prompt
  1452.               (buffer-substring-no-properties 
  1453.                (match-beginning 0) (- (match-end 0) 1))))
  1454.       (set-buffer old-buffer)
  1455.       prompt)))
  1456.  
  1457. ;;; Update the different cell types
  1458.  
  1459. (defun emaxima-update-cell (&optional tex)
  1460.   "Send the current cell's contents to Maxima, and return the results."
  1461.   (maxima-start)
  1462.   (setq tex (and tex emaxima-tex-lisp-file))
  1463.   (if (emaxima-cell-p)
  1464.       (save-excursion
  1465.         (if (emaxima-session-cell-p)
  1466.             (if tex
  1467.                 (emaxima-tex-update-session-cell)
  1468.               (emaxima-update-session-cell))
  1469.           (emaxima-delete-output)
  1470.           (let ((end)
  1471.                 (cell (emaxima-get-cell-contents)))
  1472.             (goto-char (emaxima-cell-end))
  1473.             (forward-line 1)
  1474.             (if (and tex (not (emaxima-noshow-cell-p)))
  1475.                 (insert "\\maximatexoutput\n")
  1476.               (insert "\\maximaoutput\n"))
  1477.             (while (or
  1478.                     (string-match "[$;]" cell)
  1479.                     (eq (string-match "[ \n]*:lisp" cell) 0))
  1480.               (if (eq (string-match "[ \n]*:lisp" cell) 0)
  1481.                   (setq end (maxima-get-lisp-end cell))
  1482.                 (setq end (1+ (string-match "[$;]" cell))))
  1483.               (if (and tex emaxima-tex-lisp-file (maxima-finished-p))
  1484.                   (emaxima-tex-on))
  1485.               (maxima-single-string (substring cell 0 end))
  1486.               (setq cell (substring cell end))
  1487.               (if (and tex 
  1488.                        (not (emaxima-noshow-cell-p))
  1489.                        (not (maxima-finished-p)))
  1490.                   (emaxima-insert-last-output-tex-noprompt)
  1491.                 (insert (emaxima-last-maxima-output-noprompt)))))))
  1492.     (error "Not in Maxima cell")))
  1493.  
  1494. (defun emaxima-update-session-cell ()
  1495.   "Send the current cell's contents to Maxima, and return the results."
  1496.   (maxima-start)
  1497.   (save-excursion
  1498.     (emaxima-delete-output)
  1499.     (let ((end)
  1500.           (cell (emaxima-get-cell-contents)))
  1501.       (goto-char (emaxima-cell-end))
  1502.       (forward-line 1)
  1503.       (insert "\\maximasession\n")
  1504.       (while (or
  1505.               (string-match "[$;]" cell)
  1506.               (eq (string-match "[ \n]*:lisp" cell) 0))
  1507.         (if (eq (string-match "[ \n]*:lisp" cell) 0)
  1508.             (setq end (maxima-get-lisp-end cell))
  1509.           (setq end (1+ (string-match "[$;]" cell))))
  1510.         (maxima-single-string (substring cell 0 end))
  1511.         (insert (emaxima-last-input-prompt))
  1512.         (insert " ")
  1513.         (while (or (string= "\n" (substring cell 0 1))
  1514.                    (string= " " (substring cell 0 1)))
  1515.           (setq cell (substring cell 1))
  1516.           (setq end (- end 1)))
  1517.         (insert (substring cell 0 end))
  1518.         (unless (string= "\n" (substring cell (- end 1) end))
  1519.           (insert "\n"))
  1520.         (insert "\n")
  1521.         (insert (emaxima-last-maxima-output))
  1522.         (setq cell (substring cell end))))))
  1523.  
  1524. (defun emaxima-tex-update-session-cell ()
  1525.   "Send the current cell's contents to Maxima, and return the results."
  1526.   (maxima-start)
  1527.   (if (not emaxima-tex-lisp-file)
  1528.       (emaxima-update-session-cell)
  1529.     (save-excursion
  1530.       (emaxima-delete-output)
  1531.       (let ((end)
  1532.             (out)
  1533.             (cell (emaxima-get-cell-contents)))
  1534.         (goto-char (emaxima-cell-end))
  1535.         (forward-line 1)
  1536.         (insert "\\maximatexsession\n")
  1537.         (while (or
  1538.                 (string-match "[$;]" cell)
  1539.                 (eq (string-match "[ \n]*:lisp" cell) 0))
  1540.           (if (eq (string-match "[ \n]*:lisp" cell) 0)
  1541.               (setq end (maxima-get-lisp-end cell))
  1542.             (setq end (1+ (string-match "[$;]" cell))))
  1543.           (if (and emaxima-tex-lisp-file (maxima-finished-p))
  1544.               (emaxima-tex-on))
  1545.           (maxima-single-string (substring cell 0 end))
  1546.           (while (or (string= "\n" (substring cell 0 1))
  1547.                      (string= " " (substring cell 0 1)))
  1548.             (setq cell (substring cell 1))
  1549.             (setq end (- end 1)))
  1550.           (insert "\\C")
  1551.           (insert (substring (emaxima-last-input-prompt) 2 -1))
  1552.           (insert ".  ")
  1553.           (insert (substring cell 0 end))
  1554.           (insert " \\\\")
  1555.           (unless (string= "\n" (substring cell (- end 1) end))
  1556.             (insert "\n"))
  1557. ;          (insert "\n")
  1558.           (emaxima-insert-last-output-tex)
  1559.           (setq cell (substring cell end)))))))
  1560.  
  1561. ;;; Update the different groups
  1562.  
  1563. (defun emaxima-update-all (arg)
  1564.   "Optionally update all cells.
  1565. With C-u prefix, update without confirmation at each cell."
  1566.   (interactive "P")
  1567.   (save-excursion
  1568.     (if arg
  1569.         (emaxima-update nil nil nil)
  1570.       (emaxima-update nil (y-or-n-p "Interactive update? ") nil))))
  1571.  
  1572. (defun emaxima-menu-update-all ()
  1573.   (interactive)
  1574.   "Update all cells"
  1575.   (emaxima-update nil nil nil))
  1576.  
  1577. (defun emaxima-tex-update-all (arg)
  1578.   "Optionally update all cells and return output in TeX form.
  1579. With C-u prefix, update without confirmation at each cell."
  1580.   (interactive "P")
  1581.   (emaxima-tex-on)
  1582.   (if arg
  1583.       (emaxima-update nil nil t)
  1584.     (emaxima-update nil (y-or-n-p "Interactive update? ") t))
  1585.   (emaxima-tex-off))
  1586.  
  1587. (defun emaxima-menu-tex-update-all ()
  1588.   (interactive)
  1589.   (emaxima-tex-on)
  1590.   (emaxima-update nil nil t)
  1591.   (emaxima-tex-off))
  1592.   
  1593.  
  1594. (defun emaxima-update-init (arg)
  1595.   "Optionally update all initialization cells.
  1596. With C-u prefix, update without confirmation at each cell."
  1597.   (interactive "P")
  1598.   (if arg
  1599.       (emaxima-update "\\[\\* Initialization Cell \\*\\]" nil nil)
  1600.     (emaxima-update "\\[\\* Initialization Cell \\*\\]" 
  1601.            (y-or-n-p "Interactive update? ") nil)))
  1602.  
  1603. (defun emaxima-tex-update-init (arg)
  1604.   "Optionally update all initialization cells and return output in TeX form.
  1605. With C-u prefix, update without confirmation at each cell."
  1606.   (interactive "P")
  1607.   (emaxima-tex-on)
  1608.   (if arg
  1609.       (emaxima-update "\\[\\* Initialization Cell \\*\\]" nil t)
  1610.     (emaxima-update "\\[\\* Initialization Cell \\*\\]" 
  1611.            (y-or-n-p "Interactive update? ") t))
  1612.   (emaxima-tex-off))
  1613.  
  1614. (defun emaxima-update-session (arg)
  1615.   "Optionally update all session cells.
  1616. With C-u prefix, update without confirmation at each cell."
  1617.   (interactive "P")
  1618.   (if arg
  1619.       (emaxima-update "session" nil nil)
  1620.     (emaxima-update "session" 
  1621.            (y-or-n-p "Interactive update? ") nil)))
  1622.  
  1623. (defun emaxima-tex-update-session (arg)
  1624.   "Optionally update all session cells.
  1625. With C-u prefix, update without confirmation at each cell."
  1626.   (interactive "P")
  1627.   (emaxima-tex-on)
  1628.   (if arg
  1629.       (emaxima-update "session" nil t)
  1630.     (emaxima-update "session" 
  1631.            (y-or-n-p "Interactive update? ") t))
  1632.   (emaxima-tex-off))
  1633.  
  1634. (defun emaxima-update-single-cell (&optional tex)
  1635.   "Send the current cell's contents to Maxima, and return the results."
  1636.   (interactive "P")
  1637.   (maxima-start)
  1638.   (setq tex (and tex emaxima-tex-lisp-file))
  1639.   (if (emaxima-cell-p)
  1640.       (save-excursion
  1641.         (if tex (emaxima-tex-on))
  1642.         (if (emaxima-session-cell-p)
  1643.             (if tex
  1644.                 (emaxima-tex-update-session-cell)
  1645.               (emaxima-update-session-cell))
  1646.           (emaxima-delete-output)
  1647.           (let ((end)
  1648.                 (cell (emaxima-get-cell-contents)))
  1649.             (goto-char (emaxima-cell-end))
  1650.             (forward-line 1)
  1651.             (if (and tex (not (emaxima-noshow-cell-p)))
  1652.                 (insert "\\maximatexoutput\n")
  1653.               (insert "\\maximaoutput\n"))
  1654.             (while (or
  1655.                     (string-match "[$;]" cell)
  1656.                     (eq (string-match "[ \n]*:lisp" cell) 0))
  1657.               (if (eq (string-match "[ \n]*:lisp" cell) 0)
  1658.                   (setq end (maxima-get-lisp-end cell))
  1659.                 (setq end (1+ (string-match "[$;]" cell))))
  1660.               (maxima-single-string (substring cell 0 end))
  1661.               (setq cell (substring cell end))
  1662.               (if (and tex 
  1663.                        (not (emaxima-noshow-cell-p))
  1664.                        (not (maxima-finished-p)))
  1665.                   (emaxima-insert-last-output-tex-noprompt)
  1666.                 (insert (emaxima-last-maxima-output-noprompt))))))
  1667.         (if tex (emaxima-tex-off)))
  1668.         (error "Not in Maxima cell")))
  1669.   
  1670. (defun emaxima-tex-update-single-cell ()
  1671.   "Send input to maxima and replace output with the result in TeX form.
  1672. Point must be in cell."
  1673.   (interactive)
  1674.   (emaxima-update-single-cell t))
  1675.  
  1676. ;;; The workhorses
  1677.  
  1678. (defun emaxima-update (kind ask tex)
  1679.   "Optionally update all KIND cells.
  1680. If ASK is non-nil, then ask whether each KIND cell is to be updated,
  1681. else update each KIND cell.  If KIND is nil, update all cells.
  1682. If TEX is non-nil, then insert \\maximatexoutput instead of \\maximaoutput."
  1683.   (setq tex (and emaxima-tex-lisp-file tex))
  1684.   (let (bypass display-start display-end cur-pos)
  1685.     (save-excursion
  1686.       (goto-char (point-min))
  1687.       (while (emaxima-forward-cell)
  1688.         (forward-line -1)
  1689.         (if (and kind (not (looking-at (concat "^\\\\beginmaxima" kind))))
  1690.             (progn
  1691.               (forward-line 1) ; Don't want the same cell next time
  1692.               nil) ; Wrong kind of cell
  1693.           ;; We have a cell of the right kind
  1694.           (setq display-start (point))
  1695.           (goto-char (emaxima-cell-end))
  1696.           (forward-line 1) ; We need to include cell trailer in narrowed region
  1697.           (end-of-line)    ; ..
  1698.           (setq display-end (point))
  1699.           (forward-line 0)
  1700.           (unwind-protect
  1701.               (progn
  1702.                 (narrow-to-region display-start display-end)
  1703.                 (goto-char (point-min))
  1704.                 (recenter 1) ; force display, just in case...
  1705.                 (forward-line 1)
  1706.                 (if (and ask (not (y-or-n-p "Update this cell? ")))
  1707.                     t
  1708.                   (emaxima-update-cell tex)
  1709.                   (sit-for 0 100)))
  1710.             (widen) ; If user aborts evaluation at prompt
  1711.             ) ; unwind-protect
  1712.           ) ; if in a valid cell
  1713.         ) ; while still types to check
  1714.       (widen)
  1715.       (sit-for 1)) ; save-excursion
  1716. ;    (beep)
  1717.     (message "Update of cells finished")))
  1718.  
  1719. (defun emaxima-eval-init ()
  1720.   "Evaluate all initialization cells, without returning the output."
  1721.   (interactive)
  1722.   (let (bypass display-start display-end cur-pos)
  1723.     (save-excursion
  1724.       (goto-char (point-min))
  1725.       (while (emaxima-forward-cell)
  1726.         (forward-line -1)
  1727.         (if (not (looking-at "^\\\\beginmaxima\\[\\* Initialization Cell \\*\\]"))
  1728.             (progn
  1729.               (forward-line 1) ; Don't want the same cell next time
  1730.               nil) ; Wrong kind of cell
  1731.           ;; We have a cell of the right kind
  1732.           (setq display-start (point))
  1733.           (goto-char (emaxima-cell-end))
  1734.           (forward-line 1) ; We need to include cell trailer in narrowed region
  1735.           (end-of-line)    ; ..
  1736.           (setq display-end (point))
  1737.           (forward-line 0)
  1738.           (unwind-protect
  1739.               (progn
  1740.                 (narrow-to-region display-start display-end)
  1741.                 (goto-char (point-min))
  1742.                 (recenter 1) ; force display, just in case...
  1743.                 (forward-line 1)
  1744.                 (emaxima-send-cell))
  1745.             (widen) ; If user aborts evaluation at prompt
  1746.             ) ; unwind-protect
  1747.           ) ; if in a valid cell
  1748.         ) ; while still types to check
  1749.       ) ; save-excursion
  1750.     (widen)
  1751. ;    (beep)
  1752.     (message "Evaluation of initialization cells finished")))
  1753.  
  1754. (defun emaxima-send-cell ()
  1755.   "Send the current cell's contents to Maxima."
  1756.   (interactive)
  1757.   (if (not (emaxima-cell-p))
  1758.       (message "Not in cell.")
  1759.     (maxima-start)
  1760.     (maxima-single-string 
  1761.      (buffer-substring-no-properties (emaxima-cell-start) (emaxima-cell-end)))))
  1762.  
  1763. (defun emaxima-replace-line-with-tex ()
  1764.   "Sends the current line to Maxima, and then replaces it with the Maxima
  1765. output in TeX form."
  1766.   (interactive)
  1767.   (if (not emaxima-tex-lisp-file)
  1768.       (emaxima-replace-line)
  1769.     (maxima-start)
  1770.     (emaxima-tex-on)
  1771.     (maxima-single-string 
  1772.      (buffer-substring-no-properties 
  1773.       (maxima-line-beginning-position) (maxima-line-end-position)))
  1774. ;    (emaxima-maxima-string "tex(%);")
  1775.     (beginning-of-line)
  1776.     (insert "% ")
  1777.     (end-of-line)
  1778.     (newline)
  1779.     (emaxima-insert-last-output-tex-noprompt)
  1780. ;    (emaxima-last-maxima-output-tex-noprompt)
  1781.     (emaxima-tex-off)))
  1782.  
  1783. (defun emaxima-replace-line ()
  1784.   "Sends the current line to Maxima, and then replaces it with the Maxima
  1785. output."
  1786.   (interactive)
  1787.   (maxima-start)
  1788.   (maxima-single-string 
  1789.    (buffer-substring-no-properties 
  1790.     (maxima-line-beginning-position) (maxima-line-end-position)))
  1791.   (beginning-of-line)
  1792.   (insert "% ")
  1793.   (end-of-line)
  1794.   (newline)
  1795.   (insert (emaxima-last-maxima-output-noprompt)))
  1796.  
  1797. ;;; The mode
  1798.  
  1799. ;; First, find out what kind of TeX mode is being used.
  1800.  
  1801. (cond
  1802.  ((eq emaxima-use-tex 'auctex)
  1803.   (require 'tex-site)
  1804.   ;; I don't think this is the best thing to do...
  1805.   (load "latex")
  1806.   (setq texmode-map LaTeX-mode-map)
  1807.   (defun texmode () (latex-mode)))
  1808.  ((eq emaxima-use-tex 'tex)
  1809.   (require 'tex-mode)
  1810.   (setq texmode-map tex-mode-map)
  1811.   (defun texmode () (tex-mode)))
  1812.  (t
  1813.   (autoload 'text-mode "text-mode")
  1814.   (setq texmode-map text-mode-map)
  1815.   (defun texmode () (text-mode))))
  1816.  
  1817. ;;; Now, define the keymap
  1818. (defvar emaxima-mode-map nil
  1819.   "The keymap for emaxima-mode")
  1820.  
  1821. (if emaxima-mode-map
  1822.     nil
  1823.   (let ((map (copy-keymap texmode-map)))
  1824.     (define-key map "\"" 'emaxima-insert-quote)
  1825.     (define-key map "$" 'emaxima-insert-dollar)
  1826.     (define-key map "\C-c\C-u" nil)
  1827.     (define-key map "\C-c+" 'emaxima-forward-cell)
  1828.     (define-key map "\C-c-" 'emaxima-backward-cell)
  1829.     (define-key map "\C-c\C-ua" 'emaxima-update-all)
  1830.     (define-key map "\C-c\C-uA" 'emaxima-tex-update-all)
  1831.     (define-key map "\C-c\C-ut" 'emaxima-eval-init)
  1832.     (define-key map "\C-c\C-ui" 'emaxima-update-init)
  1833.     (define-key map "\C-c\C-uI" 'emaxima-tex-update-init)
  1834.     (define-key map "\C-c\C-us" 'emaxima-update-session)
  1835.     (define-key map "\C-c\C-uS" 'emaxima-tex-update-session)
  1836.     (define-key map "\C-c\C-o" 'emaxima-create-standard-cell)
  1837.     (define-key map "\C-c\C-p" 'emaxima-create-session-cell)
  1838.     (define-key map "\C-c\C-n" 'emaxima-create-noshow-cell)
  1839.     (define-key map "\C-c\C-ul" 'emaxima-replace-line)
  1840.     (define-key map "\C-c\C-uL" 'emaxima-replace-line-with-tex)
  1841.     (define-key map "\C-c\C-k"  'maxima-stop)
  1842.     ;; And some emaxima keys that make sense in cells
  1843.     (define-key map "\C-c\C-v" 'emaxima-send-cell)
  1844.     (define-key map "\C-c\C-uc" 'emaxima-update-single-cell)
  1845.     (define-key map "\C-c\C-uC" 'emaxima-tex-update-single-cell)
  1846.     (define-key map "\C-c\C-d" 'emaxima-delete-output)
  1847.     (define-key map "\C-c\C-t" 'emaxima-toggle-init)
  1848.     (define-key map "\C-c\C-x" 'emaxima-package-part)
  1849.     (define-key map "\C-c@" 'emaxima-assemble)
  1850.     (define-key map "\C-c\C-h" 'maxima-help)
  1851.     (define-key map "\C-c\C-i" 'maxima-info)
  1852.     (define-key map [(control c) (control tab)] 'emaxima-insert-complete-name)
  1853.     (setq emaxima-mode-map map)))
  1854.  
  1855. ;;; A function for font-locking
  1856. (defun emaxima-match-cells (limit)
  1857.   "Used to fontify whatever's between \\beginmaxima and \\endmaxima."
  1858.   (when (re-search-forward "\\\\beginmaxima" 
  1859.                            limit t)
  1860.     (let ((beg (match-end 0)) end)
  1861.       (if (search-forward "\\endmaxima"
  1862.                           limit 'move)
  1863.           (setq end (match-beginning 0))
  1864.         (setq end (point)))
  1865.       (store-match-data (list beg end))
  1866.       t)))
  1867.  
  1868. (define-derived-mode emaxima-mode tex-mode  "EMaxima"
  1869.   "This is a mode intended to allow the user to write documents that
  1870. include Maxima code.  The file can be LaTeXed to produce nice 
  1871. looking output (although that isn't necessary, of course), and so the
  1872. mode is an extension of tex-mode (AucTeX).
  1873. The units of Maxima code that are worked with are \"cells\", which are 
  1874. delimited by \"\\beginmaxima\" and \"\\endmaxima\". The cells can be evaluated 
  1875. individually, as a group, and the output can be returned as Maxima output 
  1876. or in TeX form.  Evaluating a cell and returning the output is called 
  1877. \"updating\" the cell.  This mode also supports some literate programming 
  1878. constructs.  (See the file \"EMaximaIntro.tex\" for more 
  1879. information.)
  1880. The commands for working with cells are:
  1881.  \\[emaxima-create-standard-cell]  create a cell         
  1882.  \\[emaxima-update-all] update all the cells 
  1883.  \\[emaxima-tex-update-all] update all the cells in TeX form 
  1884.  \\[emaxima-forward-cell] go to the next cell 
  1885.  \\[emaxima-backward-cell] go to the previous cell
  1886.  \\[emaxima-eval-init] evaluate all  initialization cells
  1887.  \\[emaxima-update-init] update all the initialization cells
  1888.  \\[emaxima-tex-update-init] update all the initialization cells in TeX form
  1889.  
  1890. (With a prefix, C-u \\[emaxima-update-all] and C-u \\[emaxima-tex-update-all] will update the cells 
  1891. without prompting)
  1892. Since the Maxima output can be returned to the EMaxima buffer,
  1893. the buffer which runs the Maxima process is not shown.
  1894.  
  1895. Single lines can be evaluated:
  1896.  \\[emaxima-replace-line] replace the current line with Maxima output
  1897.  \\[emaxima-replace-line-with-tex] replace the current line with Maxima output in TeX form.
  1898.  
  1899. Within a cell, the following commands are available:\\<emaxima-maxima-map>
  1900.  \\[emaxima-delete-output]  delete the cell's output
  1901.  \\[emaxima-update-cell]  update a cell 
  1902.  \\[emaxima-tex-update-cell] update a cell in TeX form
  1903.  \\[emaxima-toggle-init] toggle initialization cells
  1904.  \\[emaxima-assemble]  assemble a cell which defines a package
  1905.  C-u \\[emaxima-assemble]  assemble a cell with references
  1906.  
  1907. Finally, the command \\[emaxima-mark-file-as-emaxima] will insert a 
  1908. %-*-EMaxima-*- at the beginning of the file (if there isn't one there 
  1909. already) so the file will begin in emaxima-mode next time it's opened.
  1910.  
  1911. \\{emaxima-mode-map}
  1912. "
  1913.   (when (or (eq emaxima-use-tex 'auctex) (eq emaxima-use-tex 'tex))
  1914.     (make-local-variable 'ispell-parser)
  1915.     (setq ispell-parser 'tex)
  1916.     (make-local-variable 'ispell-tex-p)
  1917.     (setq ispell-tex-p t))
  1918.   (make-local-variable 'texmathp-tex-commands)
  1919.   (setq texmathp-tex-commands 
  1920.      '(("\\endmaxima" sw-off)))
  1921.   (when (eq emaxima-use-tex 'auctex)
  1922.     (require 'font-latex)
  1923.     (defvar emaxima-keywords
  1924.       (append font-latex-keywords-2
  1925.               '((emaxima-match-cells (0 font-lock-function-name-face t t))
  1926.                 ("\\(\\\\\\(beginmaxima\\(?:noshow\\|session\\)?\\|endmaxima\\(?:noshow\\|session\\)?\\|maxima\\(?:output\\|session\\|tex\\(?:output\\|session\\)\\)\\)\\)"
  1927.                  (0 font-lock-keyword-face t t))))
  1928.       "Keywords for EMaxima font-locking.")
  1929.     (make-local-variable 'font-lock-defaults)
  1930.     (setq font-lock-defaults 
  1931.           '(emaxima-keywords
  1932.             nil nil ((?\( . ".") (?\) . ".") (?$ . "\"")) nil
  1933.             (font-lock-comment-start-regexp . "%")
  1934.             (font-lock-mark-block-function . mark-paragraph))))
  1935.   (if (maxima-running)
  1936.      (emaxima-load-tex-library))
  1937.   (add-hook 'inferior-maxima-mode-hook 'emaxima-load-tex-library)
  1938. ;  (if running-xemacs 
  1939. ;      (add-hook 'inferior-maxima-mode-hook (lambda () (sit-for 1))))
  1940.   (run-hooks 'emaxima-mode-hook))
  1941.  
  1942. ;;; Now, the menu.
  1943. (easy-menu-define emaxima-menu emaxima-mode-map
  1944.   "EMaxima mode menu"
  1945.   '("EMaxima"
  1946.     ("Cells"
  1947.      ["Create cell"  emaxima-create-standard-cell 
  1948.                 (not (emaxima-standard-cell-p))]
  1949.      ["Create session cell" emaxima-create-session-cell 
  1950.                 (not (emaxima-session-cell-p))]
  1951.      ["Create noshow cell"  emaxima-create-noshow-cell 
  1952.                 (not (emaxima-noshow-cell-p))]
  1953.      ["Send cell"  emaxima-send-cell (emaxima-cell-p)]
  1954.      ["Update cell"   emaxima-update-single-cell (emaxima-cell-p)]
  1955.      ["TeX update cell"  emaxima-tex-update-single-cell (emaxima-cell-p)]
  1956.      ["Delete output"   emaxima-delete-output (emaxima-cell-p)]
  1957.      ["Toggle initialization"  emaxima-toggle-init (emaxima-standard-cell-p)]
  1958.      ["Mark as package part" emaxima-package-part (emaxima-standard-cell-p)]
  1959.      ["Insert complete name" emaxima-insert-complete-name 
  1960.                                                   (emaxima-standard-cell-p)]
  1961.      ["Forward cell"  emaxima-forward-cell]
  1962.      ["Backwards cell"  emaxima-backward-cell])
  1963.     ("Update"
  1964.      ["Update line"   emaxima-replace-line (not (emaxima-cell-p))]
  1965.      ["Update all cells"  emaxima-menu-update-all]
  1966.      ["Update session cells" emaxima-update-session]
  1967.      ["Update initialization cells"  emaxima-update-init]
  1968.      "---"
  1969.      ["TeX update line"   emaxima-replace-line-with-tex (not (emaxima-cell-p))]
  1970.      ["TeX update all cells"  emaxima-menu-tex-update-all]
  1971.      ["TeX update initialization cells"  emaxima-tex-update-init])
  1972.     ("Process"
  1973.      ["Start a Maxima process"   maxima-start
  1974.       (not (processp maxima-process))]
  1975.      ["Run Maxima on region"  maxima-region]
  1976.      ["Run Maxima on initialization cells"  emaxima-eval-init]
  1977.      ["Kill Maxima process"  maxima-stop (processp maxima-process)])
  1978.     ("Misc"
  1979.      ["Indent region"   maxima-indent-region (emaxima-cell-p)]
  1980.      ["Short comment"  maxima-short-comment (emaxima-cell-p)]
  1981.      ["Long comment" maxima-long-comment (emaxima-cell-p)]
  1982.      ["Mark file as EMaxima"  emaxima-mark-file-as-emaxima])
  1983.     ("Web"
  1984.      ["Assemble cell"  emaxima-assemble-cell 
  1985.       (and (emaxima-cell-p) (emaxima-reference-p))]
  1986.      ["Assemble package"  emaxima-assemble-package 
  1987.       (and (emaxima-cell-p) (emaxima-reference-p))])
  1988.     ("Help"
  1989.      ["Manual"   maxima-info]
  1990.      ["Describe"  maxima-help])))
  1991.  
  1992. ;;; The next line is necessary for XEmacs
  1993. (if (featurep 'xemacs)
  1994.     (easy-menu-add emaxima-menu emaxima-mode-map))
  1995.   
  1996. ;;; emaxima.el ends here
  1997.